import * as step from "@flow/step"
import os from "node:os"
import process from "node:process"
import {getArch, getPlatform, PLATFORM_DARWIN} from "./util";
import path from "node:path"
import {exportEnvVar} from "@flow/step/lib/env";

export async function installJdk(inputJdkVersion: string): Promise<void> {
    let arch: string = getArch();
    let platform: string = getPlatform()
    let toolName: string = "jdk"
    let jdkVersion: string = mapJdkVersion(inputJdkVersion);

    let cachedJdkVersions: string[] = await step.tool.whichAllVersions(toolName);
    for (let cachedJdkVersion of cachedJdkVersions) {
        if (cachedJdkVersion === jdkVersion) {
            let foundJdkPath = await step.tool.which(toolName, jdkVersion)
            step.info(`Found cached jdk version ${cachedJdkVersion} in ${foundJdkPath}, skip the installation.`)
            setupJava(foundJdkPath)
            return
        }
    }

    // 开始从tool registry下载安装Java
    let toolRegistryBaseUrl = getToolRegistryBaseUrl();
    if (toolRegistryBaseUrl === undefined) {
        step.error("Install jdk failed, can not resolve tool registry base url from 'FLOW_TOOL_REGISTRY_URL'")
        throw new Error("resolve tool registry failed")
    }

    let toolRegistryUrl = getToolDownloadUrl(toolRegistryBaseUrl, toolName, jdkVersion, platform, arch)
    let downloadUrl = getToolDownloadUrl(toolRegistryUrl, toolName, jdkVersion, platform, arch)

    let jdkDownloadPath = await step.tool.download(downloadUrl)
    let jdkExtractedDir = await step.tool.extract(jdkDownloadPath)
    let jdkCachedPath = await step.tool.cacheDir(jdkExtractedDir, toolName, jdkVersion)

    setupJava(jdkCachedPath)

    step.info(`Install Jdk ${jdkVersion} successfully`)
    step.info(`  jdk version : ${jdkVersion}`)
    step.info(`  install path: ${jdkCachedPath}`)
    step.info(`  source      : ${downloadUrl}`)
}

function setupJava(jdkPath: string): void {
    let platform: string = getPlatform()
    let javaHome: string = jdkPath
    if (platform === PLATFORM_DARWIN) {
        javaHome = path.join(javaHome, "Contents/Home")
    }
    let javaBinPath = path.join(javaHome, "bin")
    step.exportEnvVar("JAVA_HOME", javaHome)
    step.addPath(javaBinPath)
}


export async function installMaven(mavenVersion: string): Promise<void> {
    let arch: string = getArch();
    let platform: string = getPlatform()
    let toolName: string = "maven"

    // 优先从缓存中查找
    let cachedMavenVersions: string[] = await step.tool.whichAllVersions(toolName);
    for (let cachedMavenVersion of cachedMavenVersions) {
        if (cachedMavenVersion === mavenVersion) {
            let foundMavenPath = await step.tool.which(toolName, mavenVersion)
            step.info(`Found cached maven version ${cachedMavenVersion} in ${foundMavenPath}, skip the installation.`)
            step.addPath(path.join(foundMavenPath, "bin"))
            return
        }
    }

    let toolRegistryBaseUrl = getToolRegistryBaseUrl();
    if (toolRegistryBaseUrl === undefined) {
        step.error("Install maven failed, can not resolve tool registry base url from 'FLOW_TOOL_REGISTRY_URL'")
        throw new Error("resolve tool registry failed")
    }

    let toolRegistryUrl = getToolDownloadUrl(toolRegistryBaseUrl, toolName, mavenVersion, platform, arch)
    let downloadUrl = getToolDownloadUrl(toolRegistryUrl, toolName, mavenVersion, platform, arch)

    let mavenDownloadPath = await step.tool.download(downloadUrl)
    let mavenExtractedDir = await step.tool.extract(mavenDownloadPath)
    let mavenCachedPath = await step.tool.cacheDir(mavenExtractedDir, toolName, mavenVersion)

    step.addPath(path.join(mavenCachedPath, "bin"))
    step.info(`Install maven ${mavenVersion} successfully`)
    step.info(`  maven version : ${mavenVersion}`)
    step.info(`  install path  : ${mavenCachedPath}`)
    step.info(`  source        : ${downloadUrl}`)
}

export function getToolDownloadUrl(toolRegistryBaseUrl: string, toolName: string,
                                   toolVersion: string, platform: string, arch: string) {
    return `${toolRegistryBaseUrl}/${toolName}/${toolName}-${toolVersion}-${platform}-${arch}.tar.gz`
}

export function getToolRegistryBaseUrl(): string | undefined {
    return process.env["FLOW_TOOL_REGISTRY_URL"]
}

function mapJdkVersion(inputJdkVersion: string): string {
    switch (inputJdkVersion) {
        case "jdk1.6":
            return "6"
        case "jdk1.7":
            return "7"
        case "jdk1.8":
            return "8"
        case "jdk1.9":
            return "9"
        case "jdk10":
            return "10"
        case "jdk11":
            return "11"
        case "jdk17":
            return "17"
        default:
            return inputJdkVersion
    }
}
